package com.code.exam.interceptor;

import com.code.exam.annotation.LoginCheck;
import com.code.exam.common.content.BaseContext;
import com.code.exam.common.properties.JwtProperties;
import com.code.exam.common.utils.JwtUtil;
import io.jsonwebtoken.Claims;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

import java.lang.reflect.Method;

/**
 * jwt令牌校验的拦截器
 */
@Slf4j
@Component
public class JwtTokenCommonInterceptor implements HandlerInterceptor {

    @Autowired
    private JwtProperties jwtProperties;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("当前线程id：" + Thread.currentThread().getId());

        // 不是方法就放行（比如静态资源）
        if (!(handler instanceof HandlerMethod)) {
            return true;
        }

        HandlerMethod handlerMethod = (HandlerMethod) handler;
        Method method = handlerMethod.getMethod();

        // 查看是否有 @LoginCheck 注解
        LoginCheck loginCheck = method.getAnnotation(LoginCheck.class);
        if (loginCheck == null) {
            // 没有注解，无需登录也能访问
            return true;
        }

        // 获取 required role
        String role = loginCheck.role(); // "admin" or "user"

        // 根据角色决定用哪个 header 名称和 secret key
        String tokenName;
        String secretKey;

        if ("admin".equals(role)) {
            tokenName = jwtProperties.getAdminTokenName();
            secretKey = jwtProperties.getAdminSecretKey();
        } else if ("user".equals(role)) {
            tokenName = jwtProperties.getUserTokenName();
            secretKey = jwtProperties.getUserSecretKey();
        } else {
            response.setStatus(401);
            log.warn("不支持的角色类型: {}", role);
            return false;
        }

        // 1. 从请求头中获取 token
        String token = request.getHeader(tokenName);
        if (token == null || token.isEmpty()) {
            response.setStatus(401);
            log.warn("请求头中无 token");
            return false;
        }

        // 2. 解析 JWT
        try {
            log.info("正在校验 {} 的 token", role);
            Claims claims = JwtUtil.parseJWT(secretKey, token);

            Long userId = null;
            String claimName = null;

            if ("admin".equals(role)) {
                claimName = "adminId";
            } else if ("user".equals(role)) {
                claimName = "userId";
            }

            Object idObj = claims.get(claimName);
            if (idObj == null) {
                response.setStatus(401);
                log.warn("{} 身份令牌缺少 {} 字段", role, claimName);
                return false;
            }

            userId = Long.valueOf(idObj.toString());

            BaseContext.setCurrentId(userId);
            BaseContext.setRole(role);

            log.info("{} 登录验证通过，ID={}", role, userId);
            return true;

        } catch (Exception ex) {
            log.warn("JWT 解析失败", ex);
            response.setStatus(401);
            return false;
        }
    }
}
